/*
 * Copyright 2010 Christoph Widulle (christoph.widulle@googlemail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */


package com.android1.amarena2d.input;

import com.android1.amarena2d.annotations.Incomplete;
import com.badlogic.gdx.math.Vector2;

//todo implement me
@Incomplete
public abstract class VirtualDigitalPadController implements TouchListener {

    boolean exclusive = true;

    Vector2 origion;
    float radius;

    boolean hit;
    int activePointer = -1;

    public VirtualDigitalPadController(final float origionX, final float origionY, final float radius) {
        this.origion = new Vector2(origionX, origionY);
        this.radius = radius;
    }

    public VirtualDigitalPadController(final Vector2 origion, final float radius) {
        this.origion = origion;
        this.radius = radius;
    }


    public boolean isExclusive() {
        return exclusive;
    }


    public VirtualDigitalPadController setExclusive(final boolean exclusive) {
        this.exclusive = exclusive;
        return this;
    }

    public Vector2 getOrigion() {
        return origion;
    }

    public void setOrigion(Vector2 origion) {
        this.origion = origion;
    }

    public float getRadius() {
        return radius;
    }

    public void setRadius(float radius) {
        this.radius = radius;
    }

    public abstract void onChange(float radius, float directionX, float directionY, float x, float y);


    @Override
    public boolean onTouchDown(float x, float y, int pointer, boolean isHit) {
        if (!isHit || (this.activePointer != -1 && this.activePointer != pointer))
            return false;

        update(x, y);
        this.hit = true;
        this.activePointer = pointer;
        return exclusive;
    }

    @Override
    public boolean onTouchUp(float x, float y, int pointer, boolean isHit) {
        if (this.activePointer != -1 && this.activePointer != pointer)
            return false;
        this.activePointer = -1;
        hit = false;
        stop();
        return exclusive;
    }

    @Override
    public boolean onTouchDragged(float x, float y, int pointer, boolean isHit) {
        if (!hit || (this.activePointer != -1 && this.activePointer != pointer))
            return false;
        update(x, y);
        return exclusive;

    }

    private void stop() {
        onChange(0, 0, 0, origion.x, origion.y);
    }

    private void update(float x, float y) {


        float diffX = x - origion.x;
        float diffY = y - origion.y;
        float len = (float) Math.sqrt(diffX * diffX + diffY * diffY);

        if (len > radius) {
            len = radius;
            if (Math.abs(diffX) > radius) {
                final float d = Math.abs(diffX) - radius;
                if (diffX > 0) {
                    diffX -= d;
                    x -= d;
                } else {
                    diffX += d;
                    x += d;
                }
            }
            if (Math.abs(diffY) > radius) {
                final float d = Math.abs(diffY) - radius;
                if (diffY > 0) {
                    diffY -= d;
                    y -= d;
                } else {
                    diffY += d;
                    y += d;
                }
            }
        }
        if (len != 0) {
            onChange(len, diffX / len, diffY / len, x, y);
        } else {
            onChange(0, 0, 0, x, y);
        }


    }


}
